﻿package src.hardware.rgbledmatrixdisplay
{
	import flash.display.Sprite;
	import flash.events.Event;
	import src.interfaces.IRGBLEDMatrixDisplay;
	import src.hardware.rgbledmatrixdisplay.LED;
	import src.hardware.rgbledmatrixdisplay.DrawPxObject;
	import com.hexagonstar.util.debug.Debug;
	
	/**
	* ...
	* @author Louis Tovar
	*/
	public class RGBLEDMatrixDisplay extends Sprite implements IRGBLEDMatrixDisplay
	{		
		private const LED_SPACING_RATIO:Number = 3;
		
		private static const LED_SPACING:int = 5;
		
		private var _ledRows:uint;
		private var _ledColumns:uint;
		private var _displayWidth:Number;
		private var _displayHeight:Number;
		
		private var ledContainer:Sprite;
		private var ledArray:Array;
		private var ledDrawBuffer:Array;
		
		private var ledRadius:Number;
		private var ledSpacing:Number;
		
		public function RGBLEDMatrixDisplay(p_columns:uint, p_rows:uint) 
		{
			_ledColumns = p_columns;
			_ledRows = p_rows;
			_displayWidth = 200;
			_displayHeight = 200;
			
			initSelf();
		}
		
		private function initSelf():void
		{
			var blockWidth:int = _displayWidth / _ledColumns;
			ledSpacing = blockWidth / LED_SPACING_RATIO;
			ledRadius = (blockWidth - ledSpacing)/2;
			
			ledDrawBuffer = new Array();
			
			ledContainer = new Sprite();
			ledArray = new Array();
			
			addChild(ledContainer);
			
			for (var columnIndex:int = 0; columnIndex < _ledColumns; columnIndex++)
			{
				ledArray.push([]);
				for (var rowIndex:int = 0; rowIndex < _ledRows; rowIndex++)
				{
					if ( !ledArray[columnIndex] )
					{
						ledArray[columnIndex].push([]);
					}
					
					var newLED:LED = new LED(ledRadius);
					newLED.x = columnIndex * (ledRadius * 2 + ledSpacing);
					newLED.y = rowIndex * (ledRadius * 2 + ledSpacing);
					
					ledContainer.addChild(newLED);
					
					ledArray[columnIndex].push(newLED);
				}
			}
			
			ledContainer.x += _displayWidth * 0.005;
			ledContainer.y += _displayHeight * 0.005;
			
			ledContainer.width = _displayWidth * 0.99;
			ledContainer.height = _displayHeight * 0.99;
			
			
			graphics.lineStyle();
			graphics.beginFill(0x000000, 1);
			graphics.drawRect(0, 0, _displayWidth, _displayHeight);
			graphics.endFill();
		}
		
		public function DrawPx(xin:uint, yin:uint, color:uint):void
		{
			ledDrawBuffer.push( new DrawPxObject(xin, yin, color) );
		}
		
		public function ReadPx(xin:uint, yin:uint):uint
		{
			return (ledArray[xin][yin] as LED).getLEDColor();
		}
		
		public function EmptyScreen():void
		{
			var column:uint = 0;
			var row:uint = 0;
			
			while (column < _ledColumns)
			{
				row = 0;
				while (row < _ledRows)
				{
					(ledArray[column][row] as LED).setLEDColor(0x303030);
					row++;
				}
				column++;
			}
		}
		
		public function ShowScreen():void
		{
			while (ledDrawBuffer.length)
			{
				var pxObject:DrawPxObject = ledDrawBuffer.shift() as DrawPxObject;
				if (ledArray[pxObject.xin][pxObject.yin])
				{
					(ledArray[pxObject.xin][pxObject.yin] as LED).setLEDColor(pxObject.color);
				}
				else
				{
					throw Error("LED at X: " + pxObject.xin + ", Y:" + pxObject.yin +" does not exist.");
				}
			}
		}
		
		public function get ledRows():uint { return _ledRows; }
		
		public function get ledColumns():uint { return _ledColumns; }
		
		public function get displayWidth():Number { return _displayWidth; }
		
		public function get displayHeight():Number { return _displayHeight; }
		
	}
	
}